package com.mycat.manager.content;

import com.mycat.auth.dto.auth.MenuResourcesDTO;
import com.mycat.manager.controller.common.IndexController;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * 菜单样式拦截器
 *
 * @author roger.
 * @email luojie@yzworld.cn
 * @date 2016/10/12
 */
public class MenuStyleInterceptor implements HandlerInterceptor {
    private static final Logger logger = LoggerFactory.getLogger(MenuStyleInterceptor.class);
    private static final String SESSION_SELECT_MENU_STYLE = "selectMenu";

    /**
     * Controller处理之前进行调用
     */
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
//        logger.info("Controller处理之前进行调用");
        return true;
    }

    /**
     * Controller的方法调用之后执行
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        String url = request.getRequestURI().toString();
//        logger.info("Controller的方法调用之后执行  : " + url);

        Session session = SecurityUtils.getSubject().getSession();
        Object indexMenu = session.getAttribute(IndexController.SESSION_INDEX_MENU);
        if (null != indexMenu) {
            List<MenuResourcesDTO> resources = (List<MenuResourcesDTO>) indexMenu;
            Map<Integer, MenuResourcesDTO> map = new HashMap<>();
            indexToMap(resources, map);

            MenuResourcesDTO currentResource = null; // 当前拦截的资源
            Iterator<Integer> indexMenuIds = map.keySet().iterator();
            while (indexMenuIds.hasNext()) {
                currentResource = map.get(indexMenuIds.next());
                if (url.equals(currentResource.getUrl())) {
                    break;
                }
            }

            Map<Integer, Map<String, Object>> menuStyle = menuAddStyle(currentResource, map);
            if (null != menuStyle && menuStyle.size() > 0) {
                session.setAttribute(SESSION_SELECT_MENU_STYLE, menuStyle);
            }
//            logger.info("选择菜单样式：{}", menuStyle.toString());
        }
    }

    /**
     * 添加当前选择菜单样式
     *
     * @param current 当前选中菜单
     * @param map     所有菜单
     * @return 样式集合
     */
    public Map<Integer, Map<String, Object>> menuAddStyle(MenuResourcesDTO current, Map<Integer, MenuResourcesDTO> map) {
        Map<Integer, Map<String, Object>> menuStyle = new HashMap<>();
        if (null == current) {
            return menuStyle;
        }
        menuStyle.put(current.getId(), new HashMap<String, Object>() {
            {
                put("id", current.getId());
                put("style", "active");
            }
        });
        if (null != current.getParent()) {
            menuAddParentStyle(current.getParent(), map, menuStyle);
        }
        return menuStyle;
    }

    /**
     * 添加父节点样式
     *
     * @param current 当前节点
     * @param map     所有菜单数据
     * @param style   样式集合
     */
    public void menuAddParentStyle(MenuResourcesDTO current, Map<Integer, MenuResourcesDTO> map, Map<Integer, Map<String, Object>> style) {
        if (null != current) {
            style.put(current.getId(), new HashMap<String, Object>() {
                {
                    put("id", current.getId());
                    put("style", "active open");
                }
            });
            MenuResourcesDTO parent = current.getParent();
            if (null != parent) {
                menuAddParentStyle(parent, map, style);
            }
        }
    }

    /**
     * 将左侧菜单栏转换为Map
     *
     * @param resources 转换前的数据
     * @param map       转换后的数据
     */
    private void indexToMap(List<MenuResourcesDTO> resources, Map<Integer, MenuResourcesDTO> map) {
        for (MenuResourcesDTO resource : resources) {
            map.put(resource.getId(), resource);
            if (null != resource.getChildren() && resource.getChildren().size() > 0) {
                indexToMap(resource.getChildren(), map);
            }
        }
    }

    /**
     * preHandle为true时才执行
     */
    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
//        logger.info("preHandle为true时才执行");
    }
}
